#include <iostream>
#include <fstream>
#include <sstream>
#include <string>
#include <vector>
#include <map>
#include <set>
#include <utility>

using namespace std;

const string &transform(const string &s, const map<string, string> &m)
{
    // 实际的转换工作:此部分是程序的核心
    auto map_it = m.find(s);
    // 如果单词在转换规则中
    if (map_it != m.end()) {
        return map_it->second;  // 使用替换短语
    } else {
        return s;  // 返回原 s
    }
}

map<string, string> buildMap(ifstream &map_file)
{
    map<string, string> trans_map;  // 保存转换规则
    string key;  // 要转换的单词
    string value;  // 替换后的单词
    // 读取第一个单词存入 key 中,剩余的单词存入 value 中
    while (map_file >> key && getline(map_file, value)) {
        if (value.size() > 1) {  // 检查是否有转换规则
            trans_map[key] = value.substr(1);  // 跳过前导空格
        } else {
            throw runtime_error("no rule for " + key);
        }
    }
    return trans_map;
}

void word_transform(ifstream &map_file, ifstream &input)
{
    auto trans_map = buildMap(map_file);  // 保存转换规则
    string text;  // 保存输入中的每一行
    while (getline(input, text)) {  // 读取一行输入
        istringstream stream(text);  // 读取每个单词
        string word;
        bool firstword = true;  // 控制是否打印空格
        while (stream >> word) {
            if (firstword) {
                firstword = false;
            } else {
                cout << " ";  // 在单词间打印一个空格
            }
            // transform 返回它的第一个参数或其转换之后的形式
            cout << transform(word, trans_map);  // 打印输出
        }
        cout << endl;  // 完成一行的转换
    }
}

int main()
{
    // 统计输入中每个单词出现的次数
    map<string, size_t> word_count; // string 到 size_t 的空 map
    set<string> exclude = {"The", "But", "And", "Or", "An", "A",
                           "the", "but", "and", "or", "an", "a"};
    string word;

    while (cin >> word) {
        // 只统计不在 exclude 中的单词
        if (exclude.find(word) == exclude.end()) {
            ++word_count[word];  // 提取 word 的计数器并将其加 1
        }
    }
    for (const auto &w : word_count) { // 对 map 中的每个元素
        // 打印结果
        cout << w.first << " occurs " << w.second
             << ((w.second > 1) ? " times " : " time ") << endl;
    }

    // 定义一个有 20 个元素的 vector，保存 0 到 9 每个整数的两个拷贝
    vector<int> ivec;
    for (vector<int>::size_type i = 0; i != 10; ++i) {
        ivec.push_back(i);
        ivec.push_back(i);  // 每个数重复保存 2 次
    }
    // iset 包含来自 ivec 的不重复元素; miset 包含所有 20 个元素
    set<int> iset(ivec.begin(), ivec.end());
    multiset<int> miset(ivec.cbegin(), ivec.cend());
    cout << ivec.size() << endl;  // 打印 20
    cout << iset.size() << endl;  // 打印 10
    cout << miset.size() << endl;  // 打印 20

    set<string>::value_type v1;         // v1 是一个 string
    set<string>::key_type v2;           // v2 是一个 string
    map<string, int>::value_type v3;    // v3 是一个 pair<const string, int>
    map<string, int>::key_type v4;      // v4 是一个 string
    map<string, int>::mapped_type v5;   // v5 是一个 int

    // 获得指向 word_count 中一个元素的迭代器
    auto map_it = word_count.begin();
    // *map_it 是一个指向 pair<const string, int> 对象的引用
    cout << map_it->first;  // 打印此元素的关键字
    cout << " " << map_it->second;  // 打印此元素的值
    map_it->first = "new key";  // 错误：关键字是 const 的
    ++map_it->second;  // 正确：可以通过迭代器改变元素

    // 向 word_count 插入元素的四种方法
    word_count.insert({word, 1});
    word_count.insert(make_pair(word, 1));
    word_count.insert(pair<string, int>(word, 1));
    word_count.insert(map<string, int>::value_type(word, 1));


    return 0;
}
